---
title: Architecture
summary: Layering, message dispatch path, composition root, and integration points.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-09-22
---

# Architecture

This host has no shared architecture across its six services beyond activation and the fault pipeline: each service class is constructed directly per request, resolves its own environment configuration and unit of work, and delegates to its own collaborators. There is no composition root and no cross-service abstraction layer.

## Hosting model

The host runs in IIS. `Global.asax` instantiates a `System.Web.HttpApplication` subclass, whose `Application_Start` constructs a single `ServiceHostFactory` and registers all six `ServiceRoute`s against it. The registration detail is on [Activation and hosting](activation-hosting.md); this page covers what happens once a message is dispatched.

| Aspect | Finding |
| --- | --- |
| Host | IIS (`System.Web.HttpApplication`) — no self-host, no Windows service host |
| Application class | `Global` (`src/WCF/SAIF.Services.WCF.Host/Global.asax.cs`) |
| Startup call chain | `Application_Start` → construct one `ServiceHostFactory` → six calls to `RouteTable.Routes.Add(new ServiceRoute(routeName, factory, serviceType))`, one per route |
| ASP.NET compatibility | `AspNetCompatibilityRequirementsMode.Allowed` on all six service classes |
| `aspNetCompatibilityEnabled` | true |
| Target framework | .NET Framework 4.6.2 |
| Platform target | x64 (`Debug`, `Release`, `ReleaseExternal` `AnyCPU` configurations) |

## Message dispatch path

```mermaid
flowchart TD
    CALLER["SOAP caller"] --> IIS["IIS + HttpApplication"]
    ROUTETBL["RouteTable<br>six ServiceRoute registrations"] --> FACTORY["ServiceHostFactory<br>one shared instance"]
    IIS --> ROUTETBL
    FACTORY --> HOST["ServiceHost per route<br>FileService / PreferenceService / WebContextService /<br>ImagingService / FaxService / SecurityService"]
    HOST --> BEHAVIOR["LogErrorBehavior<br>installs ErrorLogErrorHandler"]
    BEHAVIOR --> OPER["Operation dispatched to the<br>routed service class"]
    OPER --> SVC["Direct collaborator construction<br>no DI container"]
    SVC --> UOW["NHibernate IUnitOfWork<br>Oracle CLM / IMG / EXTUR, SQL Server NETFRAMEWORK/APPM"]
    UOW --> DB["(Oracle / SQL Server)"]
    OPER --> DOWN["Legacy.Fax SOAP proxy<br>FaxService only"]
    OPER --> ERR["ErrorLogErrorHandler<br>logs, returns false"]
```

## Layer responsibilities

| Layer | Type | Responsibility |
| --- | --- | --- |
| `Global` | `System.Web.HttpApplication` | Application start-up and service route registration |
| `SAIF.Services.WCF.Services.FileService` | Service implementation | Message handling and delegation to `System.IO` directly |
| `SAIF.Services.WCF.Services.PreferenceService` | Service implementation | Message handling and delegation to `Repository<Preference>` over an Oracle unit of work |
| `SAIF.Services.WCF.Services.WebContextService` | Service implementation | Message handling and delegation to `Repository<WebContextItem>` over a SQL Server unit of work |
| `SAIF.Services.WCF.Services.ImagingService` | Service implementation | Message handling and delegation to an Oracle `Image` repository and an internally-constructed `FileService` |
| `SAIF.Services.WCF.Services.FaxService` | Service implementation | Message handling and delegation to an internally-constructed `FileService` and the `FaxServiceProxy` outbound client |
| `SAIF.Services.WCF.Services.Security.SecurityService` | Service implementation | Message handling and delegation to `UserFactory`, `ADService`, and `AuthorizationCacheService` |
| `ErrorLogErrorHandler` | `IErrorHandler` | Exception logging and fault production — see [Faults and error pipeline](faults.md) |

## Service contracts

The six `[ServiceContract]` interfaces — `IFileService`, `IPreferenceService`, `IWebContextService`, `IImagingService`, `IFaxService`, `ISecurityService` — are **external**: they are not present anywhere in this repository. They appear only in `using` directives and one fully-qualified base-type reference, and are attributed to `SAIF.Framework.Core` (2.0.22181.2), arriving transitively rather than through a direct reference, `<ProjectReference>`, or `packages.config` entry. This is a normal, expected state for this host and is not a gap: the operation surface documented throughout this set is derived from each implementing class's public members and the route registrations, not from the (unavailable) contract source.

| Service class | Declared contract | Contract location | Resolved how |
| --- | --- | --- | --- |
| `SAIF.Services.WCF.Services.FileService` | `IFileService` | External — `SAIF.Services.WCF.Contracts` | `using` directive only, assembly arrives transitively in `SAIF.Framework.Core` |
| `SAIF.Services.WCF.Services.PreferenceService` | `IPreferenceService` | External — `SAIF.Services.WCF.Contracts` | `using` directive only, assembly arrives transitively in `SAIF.Framework.Core` |
| `SAIF.Services.WCF.Services.WebContextService` | `IWebContextService` | External — `SAIF.Services.WCF.Contracts` | `using` directive only, assembly arrives transitively in `SAIF.Framework.Core` |
| `SAIF.Services.WCF.Services.ImagingService` | `IImagingService` | External — `SAIF.Services.WCF.Contracts` | `using` directive only, assembly arrives transitively in `SAIF.Framework.Core` |
| `SAIF.Services.WCF.Services.FaxService` | `IFaxService` | External — `SAIF.Services.WCF.Contracts` | `using` directive only, assembly arrives transitively in `SAIF.Framework.Core` |
| `SAIF.Services.WCF.Services.Security.SecurityService` | `ISecurityService` | External — `SAIF.Services.WCF.Contracts` | `using` directive only, assembly arrives transitively in `SAIF.Framework.Core` |

| Aspect | Finding |
| --- | --- |
| Contract assembly | `SAIF.Services.WCF.Contracts` |
| Present in repository | No — external |
| Arrives via | `SAIF.Framework.Core` 2.0.22181.2 (transitive) |
| Operation surface derived from | Implementing class public members + route registrations |
| Consequence for this document set | Operation names, parameters, and return types are read from the six implementing classes; any `[OperationContract]` name override, `[FaultContract]` declaration, or `IsOneWay` setting on the external interfaces could not be inspected and is not assumed |

## Composition root

**No dependency-injection container exists in this host.** A repository-wide search for `ContainerBuilder`, `RegisterType`, `RegisterAssemblyTypes`, `RegisterModule`, `builder.Build(`, `: Autofac.Module`, and the bare token `Autofac` returned zero matches in host source. `Autofac` 3.5.2 is referenced in `WCF.csproj`/`packages.config` but is unused by this host's code — either an unused reference or a run-time requirement of the `SAIF.Framework.Core` closure.

| Field | Value |
| --- | --- |
| **Container present** | No — collaborators constructed directly in each service's parameterless constructor |
| **Project** | — |
| **File** | — |
| **Entry method** | — |
| **Invoked from** | — |
| **Instance provider** | WCF default (parameterless constructor) |
| **Additional registration files** | None |

Every collaborator — `WcfEnvironmentService`, `OracleUnitOfWorkFactory`, `SqlServerUnitOfWorkFactory`, `Repository<T>`, `UserFactory`, `ContactFactory`, `ADService`, `FileService`, `FaxServiceProxy`, `ErrorLogErrorHandler`, `WindowsEnvironmentService`, `LogService` — is constructed with `new` against a concrete class inside the consuming type's parameterless constructor or a per-call method; see [Dependencies](dependencies.md) for the full construction table.

## Instancing and concurrency

| Aspect | Finding |
| --- | --- |
| `InstanceContextMode` | Not declared — WCF default `PerSession` |
| `ConcurrencyMode` | Not declared — WCF default `Single` |
| Declared in | Not declared on any of the six service classes |
| Shared mutable state | `SecurityService.ldap_external` — a `private static` field mutated from an instance constructor on every request and read by the `static` method `IsAuthorizedExternal`; see [Tech debt](tech-debt.md). `AuthorizationCacheService`'s `HttpContext.Current.Cache`-backed cache is also process-wide shared state, by design. |

## Design constraints
- All six services depend on `aspNetCompatibilityEnabled="true"` because `SecurityService.LogRequestDetails` and `AuthorizationCacheService.IsAuthorized` both read `HttpContext.Current`, which only exists under ASP.NET compatibility.
- `FaxService` and `ImagingService` both construct a `FileService` directly (`new FileService()`), sharing its unauthorized, unconstrained file-write path between the routed surface and internal callers.

## Integration points

| System | Type | Purpose |
| --- | --- | --- |
| Oracle `CLM` | Database | `PreferenceService` persistence |
| Oracle `IMG` | Database | `ImagingService` image id reservation |
| Oracle `EXTUR` | Database | `SecurityService` user/employee resolution |
| SQL Server `NETFRAMEWORK`/`APPM` | Database | `WebContextService` persistence |
| Active Directory (`corp.saif.com`, external LDAP host) | Directory service | `SecurityService` and `PreferenceService.GetDefaultPrinter` identity resolution |
| Legacy.Fax | Downstream SOAP service | `FaxService.SendFax` dispatch — see [Dependencies](dependencies.md) |
| Local/network filesystem | File share | `FileService` read/write/delete; `ImagingService`'s import queue; `FaxService`'s temp folder |

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Activation and hosting](activation-hosting.md)
- [Operations](operations.md)
- [Faults and error pipeline](faults.md)
- [Authentication and authorization](authentication-authorization.md)
- [Dependencies](dependencies.md)
- [Configuration](configuration.md)
- [Operations and processes](operations-processes.md)
- [Business rules](business-rules.md)
- [Data model](data-model.md)
- [Operational runbook](operational-runbook.md)
- [Tech debt](tech-debt.md)

## Sources
- src/WCF/SAIF.Services.WCF.Host/Global.asax.cs
- src/WCF/SAIF.Services.WCF.Host/WCF.csproj
- src/WCF/SAIF.Services.WCF.Host/Extensions/LogErrorBehaviorAttribute.cs
- src/WCF/SAIF.Services.WCF.Host/Services/Security/SecurityService.cs
